package engine

import (
	"fmt"
	"net/http"

	"gitcode.com/eteam/sae.git/storage"
	"gitcode.com/eteam/sae.git/types"
	"github.com/gin-gonic/gin"
)

type SkillProvider interface {
	GetInfo() *types.Skill
	OnInit(taskHandler TaskHandler) error
	OnMessage(userId, userRole string, taskItem *storage.TaskInfoDbItem, taskHandler TaskHandler, rawReq *http.Request) error
}

type UserInfo struct {
	UserId   string `json:"userId"`
	UserRole string `json:"userRole"`
	UserName string `json:"userName"`
}

type AuthProvider interface {
	//获取用户信息
	GetUserInfo(req *http.Request) (*UserInfo, error)
}

type GuessSkillFunc func(skillInfoList []*types.Skill, message *types.Message) (string, error)

type InitGinFunc func(ginEngine *gin.Engine) error

type EngineConfig struct {
	StorageHandle     *storage.StorageHandle
	SkillProviderList []SkillProvider
	AuthProvider      AuthProvider
	GuessSkillFunc    GuessSkillFunc
	InitGinFunc       InitGinFunc
}

type SimpleAgentEngine struct {
	cfg       *EngineConfig
	ginEngine *gin.Engine
}

func NewSimpleAgentEngine(cfg *EngineConfig) (*SimpleAgentEngine, error) {
	if cfg.StorageHandle == nil {
		return nil, fmt.Errorf("miss StorageHandle config")
	}
	if cfg.SkillProviderList == nil {
		return nil, fmt.Errorf("miss SkillProviderList config")
	}
	if cfg.AuthProvider == nil {
		return nil, fmt.Errorf("miss AuthProvider config")
	}
	if cfg.GuessSkillFunc == nil {
		return nil, fmt.Errorf("miss GuessSkillFunc config")
	}
	ginEngine := gin.New()

	if cfg.InitGinFunc != nil {
		err := cfg.InitGinFunc(ginEngine)
		if err != nil {
			return nil, err
		}
	}

	ret := &SimpleAgentEngine{
		cfg:       cfg,
		ginEngine: ginEngine,
	}
	ret.initRouteGroup(ginEngine.Group("/api/v1"))
	return ret, nil
}

func (sae *SimpleAgentEngine) initRouteGroup(routerGroup *gin.RouterGroup) {
	//获取用户信息
	routerGroup.GET("/user/info", sae.getUserInfo)
	//列出技能
	routerGroup.GET("/skills", sae.listSkill)
	//选出最匹配技能
	routerGroup.POST("/skill/guess", sae.guessSkill)
	//列出任务
	routerGroup.GET("/tasks", sae.listTask)
	//创建任务
	routerGroup.POST("/task/create", sae.createTask)
	//获取某个任务数据
	routerGroup.GET("/task/:taskId/data", sae.getTaskData)
	//发送消息给任务
	routerGroup.POST("/task/:taskId/message", sae.processTaskMessage)
	//监听任务事件
	routerGroup.GET("/task/:taskId/event", sae.watchTaskEvent)
	//上传文件
	routerGroup.POST("/file/upload", sae.uploadFile)
	//访问文件
	routerGroup.GET("/file/:fileId/:fileToken", sae.downloadFile)
}

func (sae *SimpleAgentEngine) Run(addr string) error {
	return sae.ginEngine.Run(addr)
}

func (sae *SimpleAgentEngine) findSkillProvider(skillId string) SkillProvider {
	for _, provider := range sae.cfg.SkillProviderList {
		if provider.GetInfo().SkillId == skillId {
			return provider
		}
	}
	return nil
}

func (sae *SimpleAgentEngine) getUserInfo(ctx *gin.Context) {
	userInfo, err := sae.cfg.AuthProvider.GetUserInfo(ctx.Request)
	if err != nil {
		ctx.String(403, err.Error())
		return
	}
	ctx.JSON(200, userInfo)
}
